﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Windows.Forms;
using Util;
using System.Diagnostics;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using System.Threading;
using AutoCompleteText;
using System.Collections;
using System.IO;

namespace ISUM_V2
{

    /// <summary>
    /// 스크린 키보드
    /// </summary>
    public partial class ScreenKeyboard : Window, ICommunication
    {

        #region 멤버변수

        /// <summary>
        /// OnActivated 에서 사용하기 위한 객체
        /// </summary>
        //private WindowInteropHelper helper;


        private bool _IsCtrl { get; set; }
        private bool _IsShift { get; set; }
        private bool _IsAlt { get; set; }
        private bool _IsCapsLock { get; set; }
        private bool _IsHangul { get; set; }
        private bool _IsNumber { get; set; }
        private bool _IsAutoCompleteText { get; set; }
        private bool _IsFunction { get; set; }
        private bool _IsMacro { get; set; }
        private bool _IsHide { get; set; }
        private bool _IsBufferFull { get; set; }
        /// <summary>
        /// Number모드의 페이지 번호로 1, 2 번까지 존재
        /// </summary>
        private int _CurrentNumberPage { get; set; }

        /// <summary>
        /// 리사이클 이벤트에 사용할 버퍼
        /// </summary>
        private string _RecycleBuffer { get; set; }

        private string _AutoCompleteBufferChar { get; set; }
        private string _AutoCompleteBufferString { get; set; }
        private string _AutoCompleteBufferEnglish { get; set; }

        private ArrayList _CustomSignal { get; set; }
        private ArrayList CurrentImage { get; set; }



        private AutoCompleteText _AutoCompleteText { get; set; }
        private Automata _Automata { get; set; }

        private MainWindow _MainWindow { get; set; }


        private MacroType _MacroType { get; set; }
        private SrzKeyboardOption _KeyboardOption { get; set; }
        private SrzDefaultOption _DefaultOption { get; set; }
        private MorseCodeFileModule _Mcfm { get; set; }




        /// <summary>
        /// 키보드의 현재 상태
        /// </summary>
        private _KeyboardStateType _CurrentKeyboardState { get; set; }

        /// <summary>
        /// 현재 윈도우의 크기 상태
        /// </summary>
        private _WindowSizeType _CurrentWindowSize { get; set; }

        /// <summary>
        /// 키보드 윈도우의 크기로 Small은 0.8배, Normal은 기본인 1배, Large는 1.5배의 크기
        /// </summary>
        public enum _WindowSizeType
        {
            Small,
            Normal,
            Large
        }

        /// <summary>
        /// 키보드 레아아웃의 7가지 상태머신이며, 차례로 한글기본, 한글 복자음 복모음, 영어 소문자, 영어 대문자, 특수키1, 특수키2, 펑션키
        /// </summary>
        public enum _KeyboardStateType
        {
            KoreanDefault,
            KoreanShift,
            EnglishLower,
            EnglishUpper,
            Special1,
            Special2,
            Function,
            Browser,
            Macro
        }

        public enum _CustomSignalType : int
        {
            A,
            Alt,
            AutoComplete,
            B,
            Back,
            C,
            CapsLock,
            Comma,
            Ctrl,
            D,
            Delete,
            Dot,
            Down,
            E,
            End,
            Enter,
            Esc,
            F,
            Function,
            G,
            H,
            HanEng,
            Hanja,
            Home,
            I,
            Insert,
            J,
            K,
            L,
            Left,
            M,
            Macro,
            Close,
            N,
            O,
            P,
            PageDown,
            PageUp,
            Q,
            R,
            Recycle,
            Right,
            S,
            Shift,
            Space,
            Number,
            T,
            Tab,
            U,
            Up,
            V,
            W,
            Win,
            WindowSize,
            X,
            Y,
            Z
        }


        public delegate void BluetoothKeyEvent ();
        private BluetoothKeyEvent[] _BluetoothKeyEvents = null;


        #endregion

        #region 생성자
        public ScreenKeyboard ( MainWindow main )
        {
            InitializeComponent();
            InitBluetoothKeyEvent();

            LoadKeyboardOption();
            InitCustomSignal();

            SetEventRectDragMove();
            InitializeVariable();

            SetWindowLocation();



            LoadMacro();

            Btn_HanEng.Click += new RoutedEventHandler( Btn_HanEng_Click );
            Btn_Shift.Click += new RoutedEventHandler( Btn_Shift_Click );
            Btn_CapsLock.Click += new RoutedEventHandler( Btn_CapsLock_Click );
            Btn_Function.Click += new RoutedEventHandler( Btn_Function_Click );
            Btn_Macro.Click += new RoutedEventHandler( Btn_Macro_Click );
            Btn_Number.Click += new RoutedEventHandler( Btn_Number_Click );
            Btn_WindowSize.Click += new RoutedEventHandler( Btn_WindowSize_Click );

            _AutoCompleteText = new AutoCompleteText(this);
            _Automata = new Automata();

            _MainWindow = main;

            this.Loaded += new RoutedEventHandler( ScreenKeyboard_Loaded );

            this.Closed += new EventHandler( ScreenKeyboard_Closed );

            /*성한 */

            InitMorseImage();



        }

        public bool GetIsHangul()
        {
            return this._IsHangul;
        }
        public void LoadMacro ()
        {
            if ( _Mcfm == null )
            {
                _Mcfm = MorseCodeFileModule.getInstance();
            }
            string pathMacro = MainWindow.GetDoubleParent() + "/Macro.data";
            if ( File.Exists( pathMacro ) )
            {
                _MacroType = (MacroType)_Mcfm.readFile( pathMacro );

                SetMacro();
            }
            else
            {
                _MacroType = new MacroType();
            }
        }
        public void LoadKeyboardOption ()
        {
            
            _Mcfm = MorseCodeFileModule.getInstance();
            
            try
            {
                string pathKeyboardOption = MainWindow.GetDoubleParent() + "/SrzMoreseCode/KeyboardOption.data";
                if (File.Exists(pathKeyboardOption))
                {
                    _KeyboardOption = (SrzKeyboardOption)_Mcfm.readFile(pathKeyboardOption);
                }
                else
                {
                    _KeyboardOption = new SrzKeyboardOption();
                }
                OnceKeyboardOption();
            }
            catch (System.Exception ex)
            {
            	
            }
            
        }

        public void LoadDefaultOption()
        {

            SetDefaultOption();

            UpdateWindowHideShow();
        }

        private void SetDefaultOption()
        {
            _Mcfm = MorseCodeFileModule.getInstance();


            string pathDefaultOption = MainWindow.GetDoubleParent() + "/SrzMoreseCode/DefaultOption.data";
            if (File.Exists(pathDefaultOption))
            {
                _DefaultOption = (SrzDefaultOption)_Mcfm.readFile(pathDefaultOption);
                this._IsHide = !_DefaultOption.IsAutoHidden;
            }
            else
            {
                _DefaultOption = new SrzDefaultOption();
            }
        }

        public void SetMacro ()
        {
            if ( _MacroType._QtoP.Count == 10 )
            {
                SetQtoP( _MacroType._QtoP[ 0 ], Tb_Q1, Tb_Q2, Tb_Q3, Tb_Q4 );
                SetQtoP( _MacroType._QtoP[ 1 ], Tb_W1, Tb_W2, Tb_W3, Tb_W4 );
                SetQtoP( _MacroType._QtoP[ 2 ], Tb_E1, Tb_E2, Tb_E3, Tb_E4 );
                SetQtoP( _MacroType._QtoP[ 3 ], Tb_R1, Tb_R2, Tb_R3, Tb_R4 );
                SetQtoP( _MacroType._QtoP[ 4 ], Tb_T1, Tb_T2, Tb_T3, Tb_T4 );
                SetQtoP( _MacroType._QtoP[ 5 ], Tb_Y1, Tb_Y2, Tb_Y3, Tb_Y4 );
                SetQtoP( _MacroType._QtoP[ 6 ], Tb_U1, Tb_U2, Tb_U3, Tb_U4 );
                SetQtoP( _MacroType._QtoP[ 7 ], Tb_I1, Tb_I2, Tb_I3, Tb_I4 );
                SetQtoP( _MacroType._QtoP[ 8 ], Tb_O1, Tb_O2, Tb_O3, Tb_O4 );
                SetQtoP( _MacroType._QtoP[ 9 ], Tb_P1, Tb_P2, Tb_P3, Tb_P4 );
            }

            if ( _MacroType._AtoL.Count == 9 )
            {
                SetAtoL( _MacroType._AtoL[ 0 ], Tb_A );
                SetAtoL( _MacroType._AtoL[ 1 ], Tb_S );
                SetAtoL( _MacroType._AtoL[ 2 ], Tb_D );
                SetAtoL( _MacroType._AtoL[ 3 ], Tb_F );
                SetAtoL( _MacroType._AtoL[ 4 ], Tb_G );
                SetAtoL( _MacroType._AtoL[ 5 ], Tb_H );
                SetAtoL( _MacroType._AtoL[ 6 ], Tb_J );
                SetAtoL( _MacroType._AtoL[ 7 ], Tb_K );
                SetAtoL( _MacroType._AtoL[ 8 ], Tb_L );
            }

            if ( _MacroType._ZtoM.Count == 7 )
            {
                SetZtoM( _MacroType._ZtoM[ 0 ], Tb_Z );
                SetZtoM( _MacroType._ZtoM[ 1 ], Tb_X );
                SetZtoM( _MacroType._ZtoM[ 2 ], Tb_C );
                SetZtoM( _MacroType._ZtoM[ 3 ], Tb_V );
                SetZtoM( _MacroType._ZtoM[ 4 ], Tb_B );
                SetZtoM( _MacroType._ZtoM[ 5 ], Tb_N );
                SetZtoM( _MacroType._ZtoM[ 6 ], Tb_M );
            }
        }
        private void SetQtoP ( string macro, TextBlock tb1, TextBlock tb2, TextBlock tb3, TextBlock tb4 )
        {
            string[] arry = macro.Split( '+' );
            if ( !arry[ 0 ].Equals( "-1" ) )
            {
                tb1.Text = WinApi.MacroKeyName[ Convert.ToInt32( arry[ 0 ] ) ];
            }
            if ( !arry[ 1 ].Equals( "-1" ) )
            {
                tb2.Text = WinApi.MacroKeyName[ Convert.ToInt32( arry[ 1 ] ) ];
            }
            if ( !arry[ 2 ].Equals( "-1" ) )
            {
                tb3.Text = WinApi.MacroKeyName[ Convert.ToInt32( arry[ 2 ] ) ];
            }
            if ( !arry[ 3 ].Equals( "-1" ) )
            {
                tb4.Text = WinApi.MacroKeyName[ Convert.ToInt32( arry[ 3 ] ) ];
            }
        }

        private void SetAtoL ( string macro, TextBlock tb )
        {
            try
            {
                macro = new FileInfo( macro ).Name;
            }
            catch ( Exception ex )
            {
                macro = "";
                Console.WriteLine( ex.Message );
            }
            tb.Text = macro;
        }

        private void SetZtoM ( string macro, TextBlock tb )
        {
            tb.Text = macro;
        }
        public void InitMorseImage ()
        {
            AddCurrentImage(); // 이미지 다담기

            _Mcfm = MorseCodeFileModule.getInstance(); // 파일모듈 인스턴스 불러오고

            SrzKeyboard srzKeyboard = (SrzKeyboard)_Mcfm.readFile( MainWindow.GetDoubleParent()+"/SrzMoreseCode/Keyboard.data" ); // 역직렬화

            Image tempImage = null; //  템프 이미지 변수

            for ( int i = 0; i < CurrentImage.Count; i++ )
            {
                tempImage = (Image)CurrentImage[ i ];
                tempImage.Source = new BitmapImage( new Uri( (string)srzKeyboard.ArrKeyBoardCustomMorseCodeSrc[ i ] ) );
            }
        }

        private void AddCurrentImage ()
        {
            CurrentImage = new ArrayList();

            CurrentImage.Add( imgMorseA );
            CurrentImage.Add( imgMorseAlt );
            CurrentImage.Add( imgMorseAutoComplete );
            CurrentImage.Add( imgMorseB );
            CurrentImage.Add( imgMorseBackSpace );
            CurrentImage.Add( imgMorseC );
            CurrentImage.Add( imgMorseCaps );
            CurrentImage.Add( imgMorseComma );
            CurrentImage.Add( imgMorseCtrl );
            CurrentImage.Add( imgMorseD );
            CurrentImage.Add( imgMorseDelete );
            CurrentImage.Add( imgMorseDot );
            CurrentImage.Add( imgMorseDown );
            CurrentImage.Add( imgMorseE );
            CurrentImage.Add( imgMorseEnd );
            CurrentImage.Add( imgMorseEnter );
            CurrentImage.Add( imgMorseEsc );
            CurrentImage.Add( imgMorseF );
            CurrentImage.Add( imgMorseFunction );
            CurrentImage.Add( imgMorseG );
            CurrentImage.Add( imgMorseH );
            CurrentImage.Add( imgMorseHanEng );
            CurrentImage.Add( imgMorseHanja );
            CurrentImage.Add( imgMorseHome );
            CurrentImage.Add( imgMorseI );
            CurrentImage.Add( imgMorseInsert );
            CurrentImage.Add( imgMorseJ );
            CurrentImage.Add( imgMorseK );
            CurrentImage.Add( imgMorseL );
            CurrentImage.Add( imgMorseLeft );
            CurrentImage.Add( imgMorseM );
            CurrentImage.Add( imgMorseMacro );
            CurrentImage.Add( imgMorseMain );
            CurrentImage.Add( imgMorseN );
            CurrentImage.Add( imgMorseO );
            CurrentImage.Add( imgMorseP );
            CurrentImage.Add( imgMorsePageDown );
            CurrentImage.Add( imgMorsePageUp );
            CurrentImage.Add( imgMorseQ );
            CurrentImage.Add( imgMorseR );
            CurrentImage.Add( imgMorseRecycle );
            CurrentImage.Add( imgMorseRight );
            CurrentImage.Add( imgMorseS );
            CurrentImage.Add( imgMorseShift );
            CurrentImage.Add( imgMorseSpace );
            CurrentImage.Add( imgMorseSpecial );
            CurrentImage.Add( imgMorseT );
            CurrentImage.Add( imgMorseTab );
            CurrentImage.Add( imgMorseU );
            CurrentImage.Add( imgMorseUp );
            CurrentImage.Add( imgMorseV );
            CurrentImage.Add( imgMorseW );
            CurrentImage.Add( imgMorseWin );
            CurrentImage.Add( imgMorseWindowSize );
            CurrentImage.Add( imgMorseX );
            CurrentImage.Add( imgMorseY );
            CurrentImage.Add( imgMorseZ );
        }

        public void InitCustomSignal ()
        {
            _Mcfm = MorseCodeFileModule.getInstance();
            SrzKeyboard srzKeyboard = (SrzKeyboard)_Mcfm.readFile(MainWindow.GetDoubleParent()+ "/SrzMoreseCode/Keyboard.data" );
            this._CustomSignal = srzKeyboard.ArrKeyBoardMorseCode;
        }

        private void InitBluetoothKeyEvent ()
        {
            _BluetoothKeyEvents = new BluetoothKeyEvent[]{
                new BluetoothKeyEvent(KeyEventA),
                new BluetoothKeyEvent(KeyEventAlt),
                new BluetoothKeyEvent(KeyEventToggleAutoCompleteText),
                new BluetoothKeyEvent(KeyEventB),
                new BluetoothKeyEvent(KeyEventBackSpace),
                new BluetoothKeyEvent(KeyEventC),
                new BluetoothKeyEvent(KeyEventCapsLock),
                new BluetoothKeyEvent(KeyEventComma),
                new BluetoothKeyEvent(KeyEventCtrl),
                new BluetoothKeyEvent(KeyEventD),
                new BluetoothKeyEvent(KeyEventDelete),
                new BluetoothKeyEvent(KeyEventPeriod),
                new BluetoothKeyEvent(KeyEventDown),
                new BluetoothKeyEvent(KeyEventE),
                new BluetoothKeyEvent(KeyEventEnd),
                new BluetoothKeyEvent(KeyEventEnter),
                new BluetoothKeyEvent(KeyEventEsc),
                new BluetoothKeyEvent(KeyEventF),
                new BluetoothKeyEvent(KeyEventFunction),
                new BluetoothKeyEvent(KeyEventG),
                new BluetoothKeyEvent(KeyEventH),
                new BluetoothKeyEvent(KeyEventToggleHanEng),
                new BluetoothKeyEvent(KeyEventHanja),
                new BluetoothKeyEvent(KeyEventHome),
                new BluetoothKeyEvent(KeyEventI),
                new BluetoothKeyEvent(KeyEventInsert),
                new BluetoothKeyEvent(KeyEventJ),
                new BluetoothKeyEvent(KeyEventK),
                new BluetoothKeyEvent(KeyEventL),
                new BluetoothKeyEvent(KeyEventLeft),
                new BluetoothKeyEvent(KeyEventM),
                new BluetoothKeyEvent(KeyEventMacro),
                new BluetoothKeyEvent(KeyEventBackMain),
                new BluetoothKeyEvent(KeyEventN),
                new BluetoothKeyEvent(KeyEventO),
                new BluetoothKeyEvent(KeyEventP),
                new BluetoothKeyEvent(KeyEventPageDown),
                new BluetoothKeyEvent(KeyEventPageUp),
                new BluetoothKeyEvent(KeyEventQ),
                new BluetoothKeyEvent(KeyEventR),
                new BluetoothKeyEvent(KeyEventRecycle),
                new BluetoothKeyEvent(KeyEventRight),
                new BluetoothKeyEvent(KeyEventS),
                new BluetoothKeyEvent(KeyEventToggleShift),
                new BluetoothKeyEvent(KeyEventSpace),
                new BluetoothKeyEvent(KeyEventToggleNumberCharacter),
                new BluetoothKeyEvent(KeyEventT),
                new BluetoothKeyEvent(KeyEventTab),
                new BluetoothKeyEvent(KeyEventU),
                new BluetoothKeyEvent(KeyEventUp),
                new BluetoothKeyEvent(KeyEventV),
                new BluetoothKeyEvent(KeyEventW),
                new BluetoothKeyEvent(KeyEventWin),
                new BluetoothKeyEvent(KeyEventChangeWindowSize),
                new BluetoothKeyEvent(KeyEventX),
                new BluetoothKeyEvent(KeyEventY),
                new BluetoothKeyEvent(KeyEventZ),
                new BluetoothKeyEvent(KeyEventShowOption),
                new BluetoothKeyEvent(KeyEventToggleHideShow)

            };
        }

        void ScreenKeyboard_Loaded ( object sender, RoutedEventArgs e )
        {
            if ( Btn_AutoCompleteOnOff != null )
            {
                ChangeKeyboardBackground( Btn_AutoCompleteOnOff, _IsAutoCompleteText );
            }
        }

        void ScreenKeyboard_Closed ( object sender, EventArgs e )
        {
            _MainWindow.MainWindow_Closed( sender, e );
        }

        void Btn_WindowSize_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventChangeWindowSize();
        }

        void Btn_Number_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventToggleNumberCharacter();
        }

        void Btn_Macro_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventMacro();
        }

        void Btn_Function_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventFunction();
        }

        void Btn_CapsLock_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventCapsLock();
        }

        void Btn_Shift_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventToggleShift();
        }

        void Btn_HanEng_Click ( object sender, RoutedEventArgs e )
        {
            KeyEventToggleHanEng();
        }

        /// <summary>
        /// 윈도우의 위치 조정
        /// </summary>
        private void SetWindowLocation ()
        {
            this.Left = 0;
            this.Top = Screen.PrimaryScreen.WorkingArea.Bottom - this.Height;
        }

        #endregion

        #region 키보드 스토리보드, 윈도우 드래그

        private delegate void DelegateStartStoryboardKeyboard ( System.Windows.Controls.Button btn );

        /// <summary>
        /// 버튼 트리거 강제동작 이벤트
        /// </summary>
        /// <param name="btn">조작할 버튼 객체</param>
        private void InvokeMethodStartStoryboardKeyboard ( System.Windows.Controls.Button btn )
        {
            btn.TabIndex = 99;
            btn.TabIndex = 100;
        }

        private void StartStoryboardKeyboard ( System.Windows.Controls.Button btn )
        {

            btn.Dispatcher.BeginInvoke( new DelegateStartStoryboardKeyboard( InvokeMethodStartStoryboardKeyboard ), btn );
        }

        public void StartHide_StoryBoard ()
        {
            _IsHide = true;
            _CurrentWindowSize = _WindowSizeType.Small;
            ChangeWindowSize();

            var sb = ( (Storyboard)this.FindResource( "Storyboard_Hide" ) );
            sb.Begin( this, true );

        }

        public void StopHide_StoryBoard ()
        {
            var sb = ( (Storyboard)this.FindResource( "Storyboard_Hide" ) );
            sb.Stop();

        }


        public void StartShow_StoryBoard ()
        {
            _IsHide = false;
            _CurrentWindowSize = _WindowSizeType.Small;
            ChangeWindowSize();

            var sb = ( (Storyboard)this.FindResource( "Storyboard_Show" ) );
            sb.Begin( this, true );

        }


        private void rectView_MouseLeftButtonDown ( object sender, MouseButtonEventArgs e )
        {
            ToggleWindowHideShow();
        }

        private void ToggleWindowHideShow ()
        {
            if ( _IsHide )
            {
                StartShow_StoryBoard();
            }
            else
            {
                StartHide_StoryBoard();
            }

        }

        private void UpdateWindowHideShow()
        {
            
            SetDefaultOption();
           

            //if (!_DefaultOption.IsAutoHidden)
            //{

            //    StartShow_StoryBoard();
            //}
            //else
            //{
            //    StartHide_StoryBoard();
            //}

        }


        private void SetEventRectDragMove ()
        {
            rectBackground.MouseLeftButtonDown += new MouseButtonEventHandler( RectBackground_MouseLeftButtonDown );

            rectView.MouseLeftButtonDown += new MouseButtonEventHandler( rectView_MouseLeftButtonDown );


        }

        /// <summary>
        /// 윈도우 드래그 무브 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void RectBackground_MouseLeftButtonDown ( object sender, MouseButtonEventArgs e )
        {
            if ( !_IsHide )
            {
                if ( this.WindowState == WindowState.Maximized )
                {
                    this.WindowState = WindowState.Normal;
                    this.Left = e.GetPosition( null ).X - 30;
                    this.Top = e.GetPosition( null ).Y - 20;

                    DragMove();
                }
                else
                {
                    this.DragMove();
                }
            }
        }

        #endregion

        #region 종료시 이벤트, 키보드 포커싱

        /// <summary>
        /// 키보드 종료시 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing ( object sender, System.ComponentModel.CancelEventArgs e )
        {
            //   MainWindow.screen_flag = false;
        }

        /// <summary>
        /// 실제 가상키보드의 포커스 유지하기 위한 오버라이드 함수(사용하기 위해서는 helper의 주석과 아래 주석을 풀어야함)
        /// </summary>
        /// <param name="e"></param>
        protected override void OnActivated ( EventArgs e )                //실제의 가상키보드처럼 쓰기위한 캐럿 포커스 유지
        {
            base.OnActivated( e );
            //  WinApi.SetWindowLong(this.helper.Handle, -20, WinApi.GetWindowLong(this.helper.Handle, -20) | 0x8000000);
        }

        #endregion

        #region 초기화

        /// <summary>
        /// 모든 변수 초기화
        /// </summary>
        private void InitializeVariable ()
        {

            _IsCtrl = false;
            _IsShift = false;
            _IsAlt = false;
            _IsCapsLock = false;
        //    _IsHangul = true;
            _IsNumber = false;
            //_IsAutoCompleteText = true;
            _IsFunction = false;
            _IsMacro = false;
            _IsHide = false;
            _IsBufferFull = false;
            _RecycleBuffer = "";
            _AutoCompleteBufferChar = "";
            _AutoCompleteBufferString = "";
            _AutoCompleteBufferEnglish = "";
            _CurrentNumberPage = 1;
            _CurrentKeyboardState = _KeyboardStateType.EnglishLower;
            //_CurrentWindowSize = _WindowSizeType.Normal;


            OnceKeyboardOption();
            LoadDefaultOption();
        }

        private void OnceKeyboardOption()
        {
            SetKeyboardOption();
            ChangeKeyboardState();
            ChangeWindowSize();
            UpdateWindowHideShow();
            ChangeKeyboardCharacterView(_CurrentKeyboardState);
        }
        

        public void SetKeyboardOption ()
        {
            _IsAutoCompleteText = _KeyboardOption.IsCheckAutoComplete;
            _IsHangul = _KeyboardOption.IsCheckKorean;

            if ( _KeyboardOption.IsCheckMaxSize == 0 )
                _CurrentWindowSize = _WindowSizeType.Large;
            else if ( _KeyboardOption.IsCheckMaxSize == 1 )
                _CurrentWindowSize = _WindowSizeType.Small;
            else if ( _KeyboardOption.IsCheckMaxSize == 2 )
                _CurrentWindowSize = _WindowSizeType.Normal;
        }

        #endregion

        #region IME체크, 키보드 싱글 이벤트, 키보드 쉬프트 이벤트

        /// <summary>        
        /// IME 체크하기        
        /// </summary>
        /// <returns>true = 한글, false = 영어</returns>
        public bool IsCheckHangul ()
        {


            IntPtr hWnd = WinApi.GetForegroundWindow();
            IntPtr IME = WinApi.ImmGetDefaultIMEWnd( hWnd );
            IntPtr IMEResult = WinApi.SendMessage( IME, 0x283, 5, 0 );
            WinApi.ImmReleaseContext( hWnd, IME );
            int currentMode = IMEResult.ToInt32();

            if ( currentMode == 1 )
            {
                return true;
            }

            return false;
        }


        /// <summary>
        /// 포커스된 윈도우의 Ime를 체크하여 메인 키보드와 한/영 상태를 맞춤
        /// </summary>
        private void ImeCheckAfterToggle ()
        {
            //Ime체크 결과와 현재 프로세스와의 플래그가 다를때 실행
            if ( !IsCheckHangul().Equals( _IsHangul ) )
            {
                ///프로그램의 IME와 타겟의 IME가 다를경우 한영전환 호출                                 
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_HANGUL, 0, 0, 0 );
            }
        }


        /// <summary>
        /// 키보드 일반 이벤트
        /// </summary>
        /// <param name="vk">WinApi.VirtualKeys Code</param>
        public void KeyEventSingle ( WinApi.VirtualKeys vk )
        {
            if ( !CheckBrowser() )
            {
                ImeCheckAfterToggle();
            }

            if ( _IsShift )
            {
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LSHIFT, 0, 0, 0 );
                WinApi.keybd_event( (byte)vk, 0, 0, 0 );
                WinApi.keybd_event( (byte)vk, 0, 2, 0 );
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LSHIFT, 0, 2, 0 );
            }
            else
            {
                WinApi.keybd_event( (byte)vk, 0, 0, 0 );
                WinApi.keybd_event( (byte)vk, 0, 2, 0 );
            }

            ToggleSpecialKey();
            ChangeKeyboardState();
        }

        /// <summary>
        /// 컨트롤, 쉬프트, 알트키가 켜져있는 상태에서 다른 키를 눌렀을 경우 토글 시키고 뷰어 원상복구
        /// </summary>
        private void ToggleSpecialKey ()
        {
            if ( _IsCtrl )
            {
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LCONTROL, 0, 2, 0 );
                _IsCtrl = !_IsCtrl;

                ChangeKeyboardBackground( Btn_Ctrl, _IsCtrl );
            }
            else if ( _IsAlt )
            {
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_MENU, 0, 2, 0 );
                _IsAlt = !_IsAlt;

                ChangeKeyboardBackground( Btn_Alt, _IsAlt );
            }
            else if ( _IsShift )
            {
                WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LSHIFT, 0, 2, 0 );
                _IsShift = !_IsShift;

                ChangeKeyboardBackground( Btn_Shift, _IsShift );
            }

        }

        /// <summary>
        /// 키보드 쉬프트 이벤트
        /// </summary>
        /// <param name="vk">WinApi.VirtualKeys Code</param>
        public void KeyEventShift ( WinApi.VirtualKeys vk )
        {
            ImeCheckAfterToggle();

            WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LSHIFT, 0, 0, 0 );
            WinApi.keybd_event( (byte)vk, 0, 0, 0 );
            WinApi.keybd_event( (byte)vk, 0, 2, 0 );
            WinApi.keybd_event( (byte)WinApi.VirtualKeys.VK_LSHIFT, 0, 2, 0 );

            ToggleSpecialKey();
            ChangeKeyboardState();
        }

        /// <summary>
        /// 컨트롤, 쉬프트, 알트키를 위한 토글 이벤트
        /// </summary>
        /// <param name="vk">이벤트 발생시킬 WinApi.VirtualKeys</param>
        /// <param name="flag">true = on, false = off</param>
        public void KeyEventToggle ( WinApi.VirtualKeys vk, bool flag )
        {
            if ( flag )
            {
                WinApi.keybd_event( (byte)vk, 0, 0, 0 );
            }
            else
            {
                WinApi.keybd_event( (byte)vk, 0, 2, 0 );
            }
        }

        #endregion

        #region 키보드 뷰어 바꾸기


        /// <summary>
        /// 각 플래그에 따른 키보드의 상태 변경
        /// </summary>
        private void ChangeKeyboardState ()
        {
            if ( CheckBrowser() && !_IsFunction && !_IsNumber && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.Browser;
            }
            else if ( _IsHangul && !_IsShift && !_IsFunction && !_IsNumber && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.KoreanDefault;
            }
            else if ( _IsHangul && _IsShift && !_IsFunction && !_IsNumber && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.KoreanShift;
            }
            else if ( !_IsHangul && _IsShift == _IsCapsLock && !_IsFunction && !_IsNumber && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.EnglishLower;
            }
            else if ( !_IsHangul && _IsShift != _IsCapsLock && !_IsFunction && !_IsNumber && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.EnglishUpper;
            }
            else if ( _IsNumber && _CurrentNumberPage == 1 && !_IsFunction && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.Special1;
            }
            else if ( _IsNumber && _CurrentNumberPage == 2 && !_IsFunction && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.Special2;
            }
            else if ( _IsFunction && !_IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.Function;
            }
            else if ( _IsMacro )
            {
                _CurrentKeyboardState = _KeyboardStateType.Macro;
            }
            else
            {
                _CurrentKeyboardState = _KeyboardStateType.KoreanDefault;
                InitializeVariable();
            }

            ChangeKeyboardCharacterView( _CurrentKeyboardState );
        }

        /// <summary>
        /// 키보드 배경인 파란색의 버튼 Opacity를 조절하는 함수
        /// </summary>
        /// <param name="btn">조절할 버튼객체</param>
        /// <param name="flag">true = 100%, false = 0%</param>
        private void ChangeKeyboardBackground ( System.Windows.Controls.Button btn, bool flag )
        {
            if ( flag )
            {
                btn.Dispatcher.BeginInvoke( new SetBtnBackgroundOpacityDelegate( SetBtnBackgroundOpacityMax ), btn );
            }
            else
            {
                btn.Dispatcher.BeginInvoke( new SetBtnBackgroundOpacityDelegate( SetBtnBackgroundOpacityMin ), btn );
            }
        }

        private delegate void SetBtnBackgroundOpacityDelegate ( System.Windows.Controls.Button btn );

        /// <summary>
        /// 해당하는 버튼의 Opacity를 100으로 변경
        /// </summary>
        /// <param name="btn">조작할 버튼 객체</param>
        private void SetBtnBackgroundOpacityMax ( System.Windows.Controls.Button btn )
        {
            ( btn.Template.FindName( "imgBtnBackground_Copy", btn ) as Image ).Opacity = 100;
        }

        /// <summary>
        /// 해당하는 버튼의 Opacity를 0으로 변경
        /// </summary>
        /// <param name="btn">조작할 버튼 객체</param>
        private void SetBtnBackgroundOpacityMin ( System.Windows.Controls.Button btn )
        {
            ( btn.Template.FindName( "imgBtnBackground_Copy", btn ) as Image ).Opacity = 0;
        }

        public delegate void NoParamDelegate ();


        /// <summary>
        /// 키보드 상태에 따른 화면 UI 변경
        /// </summary>
        /// <param name="type">_KeyboardStateType 타입의 현재 키보드 상태를 넘김</param>
        public void ChangeKeyboardCharacterView ( _KeyboardStateType type )
        {
            switch ( type )
            {
                case _KeyboardStateType.KoreanDefault:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasKoreanDefault ) );
                    break;

                case _KeyboardStateType.KoreanShift:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasKoreanShift ) );
                    break;

                case _KeyboardStateType.EnglishLower:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasEnglishLower ) );
                    break;

                case _KeyboardStateType.EnglishUpper:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasEnglishUpper ) );
                    break;

                case _KeyboardStateType.Special1:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasSpecial1 ) );
                    break;

                case _KeyboardStateType.Special2:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasSpecial2 ) );
                    break;

                case _KeyboardStateType.Function:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasFunction ) );
                    break;

                case _KeyboardStateType.Browser:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasBrowser ) );
                    break;

                case _KeyboardStateType.Macro:
                    this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowCanvasMacro ) );
                    break;
            }
        }

        /// <summary>
        /// 한글 기본 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasKoreanDefault ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Visible;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 한글 복자음, 복모음 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasKoreanShift ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Visible;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 영어 소문자 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasEnglishLower ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Visible;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 영어 대문자 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasEnglishUpper ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Visible;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 특수문자1 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasSpecial1 ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Visible;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 특수문자2 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasSpecial2 ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Visible;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 펑션 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasFunction ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Visible;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 브라우저 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasBrowser ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Visible;
            Canvas_Macro.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 매크로 키각 뷰어로 변경
        /// </summary>
        public void ShowCanvasMacro ()
        {
            Canvas_KoreanDefault.Visibility = Visibility.Hidden;
            Canvas_KoreanShift.Visibility = Visibility.Hidden;
            Canvas_EnglishLower.Visibility = Visibility.Hidden;
            Canvas_EnglishUpper.Visibility = Visibility.Hidden;
            Canvas_Special1.Visibility = Visibility.Hidden;
            Canvas_Special2.Visibility = Visibility.Hidden;
            Canvas_Function.Visibility = Visibility.Hidden;
            Canvas_Browser.Visibility = Visibility.Hidden;
            Canvas_Macro.Visibility = Visibility.Visible;
        }


        /// <summary>
        /// 키보드 윈도우의 크기 변경, 각각 0.8배 1배 1.5배로 변경가능
        /// </summary>
        private void ChangeWindowSize ()
        {

            if ( _CurrentWindowSize == _WindowSizeType.Small )
            {
                _CurrentWindowSize = _WindowSizeType.Normal;
                this.Width = 800;
                this.Height = 330;
                ShowTextBoxNormal();
            }
            else if ( _CurrentWindowSize == _WindowSizeType.Normal )
            {
                _CurrentWindowSize = _WindowSizeType.Large;
                this.Width = 1200;
                this.Height = 495;
                ShowTextBoxLarge();
            }
            else
            {
                _CurrentWindowSize = _WindowSizeType.Small;
                this.Width = 640;
                this.Height = 264;
                ShowTextBoxSmall();
            }

            SetWindowLocation();

        }

        /// <summary>
        /// 윈도우 크기 0.8배 아이콘으로 변경
        /// </summary>
        private void ShowTextBoxSmall ()
        {
            tbWindowSizeSmall.Visibility = Visibility.Visible;
            tbWindowSizeNormal.Visibility = Visibility.Hidden;
            tbWindowSizeLarge.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 윈도우 크기 1배 아이콘으로 변경
        /// </summary>
        private void ShowTextBoxNormal ()
        {
            tbWindowSizeSmall.Visibility = Visibility.Hidden;
            tbWindowSizeNormal.Visibility = Visibility.Visible;
            tbWindowSizeLarge.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 윈도우 크기 1.5배 아이콘으로 변경
        /// </summary>
        private void ShowTextBoxLarge ()
        {
            tbWindowSizeSmall.Visibility = Visibility.Hidden;
            tbWindowSizeNormal.Visibility = Visibility.Hidden;
            tbWindowSizeLarge.Visibility = Visibility.Visible;
        }



        #endregion




        #region KeyEvent Package


        private void KeyEventOnceMacroQtoP ( int index )
        {
            string []arr = _MacroType._QtoP[ index ].Split( '+' );

            if ( arr.Length == 4 )
            {

                for ( int i=0; i < 4; i++ )
                {
                    if ( !arr[ i ].Equals( "-1" ) )
                    {
                        KeyEventMacroDown( WinApi.MacroKey[ Convert.ToInt32( arr[ i ] ) ] );
                    }
                }

                for ( int i=3; i >= 0; i-- )
                {
                    if ( !arr[ i ].Equals( "-1" ) )
                    {
                        KeyEventMacroUp( WinApi.MacroKey[ Convert.ToInt32( arr[ i ] ) ] );
                    }
                }
            }
        }

        private void KeyEventOnceMacroAtoL ( string process )
        {
            if ( process != String.Empty )
            {
                System.Diagnostics.Process ps = new System.Diagnostics.Process();
                ps.StartInfo.FileName = process;
                ps.Start();
            }
        }

        private void KeyEventOnceMacroZtoM ( string message )
        {
            if ( message != String.Empty )
            {
                SendKeys.SendWait( message );
            }
        }


        private static void KeyEventMacroDown ( int keyIndex )
        {
            WinApi.keybd_event( (byte)keyIndex, 0, 0, 0 );
        }

        private static void KeyEventMacroUp ( int keyIndex )
        {
            WinApi.keybd_event( (byte)keyIndex, 0, 2, 0 );
        }


        public void KeyEventQ ()
        {

            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 1
                    KeyEventSingle( WinApi.VirtualKeys.VK_1 );
                }
                else
                {
                    // /
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_2 );
                }

            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F1 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 0 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_Q );
                SetAutoCompleteBufferChar( "ㅂ", "ㅃ", "Q", "q" );
            }

            StartStoryboardKeyboard( Btn_Q );
        }



        public void KeyEventW ()
        {

            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 2
                    KeyEventSingle( WinApi.VirtualKeys.VK_2 );
                }
                else
                {
                    // _
                    SendKeys.SendWait( "_" );
                }

            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F2 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 1 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_W );
                SetAutoCompleteBufferChar( "ㅈ", "ㅉ", "W", "w" );
            }

            StartStoryboardKeyboard( Btn_W );
        }

        public void KeyEventE ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 3
                    KeyEventSingle( WinApi.VirtualKeys.VK_3 );
                }
                else
                {
                    // |
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_5 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F3 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 2 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_E );
                SetAutoCompleteBufferChar( "ㄷ", "ㄸ", "E", "e" );
            }

            StartStoryboardKeyboard( Btn_E );
        }

        public void KeyEventR ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 4
                    KeyEventSingle( WinApi.VirtualKeys.VK_4 );
                }
                else
                {
                    // `
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_3 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F4 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 3 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_R );
                SetAutoCompleteBufferChar( "ㄱ", "ㄲ", "R", "r" );
            }

            StartStoryboardKeyboard( Btn_R );
        }

        public void KeyEventT ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 5
                    KeyEventSingle( WinApi.VirtualKeys.VK_5 );
                }
                else
                {
                    // '
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_7 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F5 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 4 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_T );
                SetAutoCompleteBufferChar( "ㅅ", "ㅆ", "T", "t" );
            }

            StartStoryboardKeyboard( Btn_T );
        }

        public void KeyEventY ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 6
                    KeyEventSingle( WinApi.VirtualKeys.VK_6 );
                }
                else
                {
                    // =
                    SendKeys.SendWait( "=" );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F6 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 5 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_Y );
                SetAutoCompleteBufferChar( "ㅛ", "ㅛ", "Y", "y" );
            }

            StartStoryboardKeyboard( Btn_Y );
        }

        public void KeyEventU ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 7
                    KeyEventSingle( WinApi.VirtualKeys.VK_7 );
                }
                else
                {
                    // <
                    SendKeys.SendWait( "<" );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F7 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 6 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_U );
                SetAutoCompleteBufferChar( "ㅕ", "ㅕ", "U", "u" );
            }

            StartStoryboardKeyboard( Btn_U );
        }
        public void KeyEventI ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 8
                    KeyEventSingle( WinApi.VirtualKeys.VK_8 );
                }
                else
                {
                    // >
                    SendKeys.SendWait( ">" );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F8 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 7 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_I );
                SetAutoCompleteBufferChar( "ㅑ", "ㅑ", "I", "i" );
            }

            StartStoryboardKeyboard( Btn_I );
        }

        public void KeyEventO ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 9
                    KeyEventSingle( WinApi.VirtualKeys.VK_9 );
                }
                else
                {
                    // [
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_4 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F9 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 8 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_O );
                SetAutoCompleteBufferChar( "ㅐ", "ㅒ", "O", "o" );
            }

            StartStoryboardKeyboard( Btn_O );
        }

        public void KeyEventP ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // 0
                    KeyEventSingle( WinApi.VirtualKeys.VK_0 );
                }
                else
                {
                    // ]
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_6 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F10 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroQtoP( 9 );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_P );
                SetAutoCompleteBufferChar( "ㅔ", "ㅖ", "P", "p" );
            }

            StartStoryboardKeyboard( Btn_P );
        }

        public void KeyEventA ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // !
                    KeyEventShift( WinApi.VirtualKeys.VK_1 );
                }
                else
                {
                    // $
                    KeyEventShift( WinApi.VirtualKeys.VK_4 );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F11 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 0 ] );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_A );
                SetAutoCompleteBufferChar( "ㅁ", "ㅁ", "A", "a" );
            }

            StartStoryboardKeyboard( Btn_A );
        }

        public void KeyEventS ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // @
                    KeyEventShift( WinApi.VirtualKeys.VK_2 );
                }
                else
                {
                    // ￦
                    SendKeys.SendWait( "￦" );
                }
            }
            else if ( _IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F12 );
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 1 ] );
            }
            else
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_S );
                SetAutoCompleteBufferChar( "ㄴ", "ㄴ", "S", "s" );
            }

            StartStoryboardKeyboard( Btn_S );
        }

        public void KeyEventD ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // #
                    KeyEventShift( WinApi.VirtualKeys.VK_3 );
                }
                else
                {
                    // ￥
                    SendKeys.SendWait( "￥" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 2 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_D );
                SetAutoCompleteBufferChar( "ㅇ", "ㅇ", "D", "d" );
            }

            StartStoryboardKeyboard( Btn_D );
        }

        public void KeyEventF ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // ^
                    KeyEventShift( WinApi.VirtualKeys.VK_6 );
                }
                else
                {
                    // €
                    SendKeys.SendWait( "€" );
                }

            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 3 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_F );
                SetAutoCompleteBufferChar( "ㄹ", "ㄹ", "F", "f" );
            }

            StartStoryboardKeyboard( Btn_F );
        }

        public void KeyEventG ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // %
                    KeyEventShift( WinApi.VirtualKeys.VK_5 );
                }
                else
                {
                    // ☎
                    SendKeys.SendWait( "☎" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 4 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_G );
                SetAutoCompleteBufferChar( "ㅎ", "ㅎ", "G", "g" );
            }

            StartStoryboardKeyboard( Btn_G );
        }

        public void KeyEventH ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // &
                    KeyEventShift( WinApi.VirtualKeys.VK_7 );
                }
                else
                {
                    // ☜
                    SendKeys.SendWait( "☜" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 5 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_H );
                SetAutoCompleteBufferChar( "ㅗ", "ㅗ", "H", "h" );
            }

            StartStoryboardKeyboard( Btn_H );
        }

        public void KeyEventJ ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // *
                    KeyEventShift( WinApi.VirtualKeys.VK_8 );
                }
                else
                {
                    // ☞
                    SendKeys.SendWait( "☞" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 6 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_J );
                SetAutoCompleteBufferChar( "ㅓ", "ㅓ", "J", "j" );
            }

            StartStoryboardKeyboard( Btn_J );
        }

        public void KeyEventK ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // (
                    KeyEventShift( WinApi.VirtualKeys.VK_9 );
                }
                else
                {
                    // {
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_4 );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 7 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_K );
                SetAutoCompleteBufferChar( "ㅏ", "ㅏ", "K", "k" );
            }

            StartStoryboardKeyboard( Btn_K );
        }

        public void KeyEventL ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // )
                    KeyEventShift( WinApi.VirtualKeys.VK_0 );
                }
                else
                {
                    // }
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_6 );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroAtoL( _MacroType._AtoL[ 8 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_L );
                SetAutoCompleteBufferChar( "ㅣ", "ㅣ", "L", "l" );
            }

            StartStoryboardKeyboard( Btn_L );
        }

        public void KeyEventZ ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // ~
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_3 );
                }
                else
                {
                    // ♬
                    SendKeys.SendWait( "♬" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 0 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_Z );
                SetAutoCompleteBufferChar( "ㅋ", "ㅋ", "Z", "z" );
            }

            StartStoryboardKeyboard( Btn_Z );
        }

        public void KeyEventX ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // "
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_7 );
                }
                else
                {
                    // ★
                    SendKeys.SendWait( "★" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 1 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_X );
                SetAutoCompleteBufferChar( "ㅌ", "ㅌ", "X", "x" );
            }

            StartStoryboardKeyboard( Btn_X );
        }

        public void KeyEventC ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // ?
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_2 );
                }
                else
                {
                    // ♥
                    SendKeys.SendWait( "♥" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 2 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_C );
                SetAutoCompleteBufferChar( "ㅊ", "ㅊ", "C", "c" );
            }

            StartStoryboardKeyboard( Btn_C );
        }

        public void KeyEventV ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // -
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_MINUS );
                }
                else
                {
                    // ←
                    SendKeys.SendWait( "←" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 3 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_V );
                SetAutoCompleteBufferChar( "ㅍ", "ㅍ", "V", "v" );
            }

            StartStoryboardKeyboard( Btn_V );
        }

        public void KeyEventB ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // +
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_PLUS );
                }
                else
                {
                    // →
                    SendKeys.SendWait( "→" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 4 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_B );
                SetAutoCompleteBufferChar( "ㅠ", "ㅠ", "B", "b" );
            }

            StartStoryboardKeyboard( Btn_B );
        }

        public void KeyEventN ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // :
                    KeyEventShift( WinApi.VirtualKeys.VK_OEM_1 );
                }
                else
                {
                    // ↑
                    SendKeys.SendWait( "↑" );
                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 5 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_N );
                SetAutoCompleteBufferChar( "ㅜ", "ㅜ", "N", "n" );
            }

            StartStoryboardKeyboard( Btn_N );
        }

        public void KeyEventM ()
        {
            if ( _IsNumber )
            {
                if ( _CurrentNumberPage == 1 )
                {
                    // ;
                    KeyEventSingle( WinApi.VirtualKeys.VK_OEM_1 );
                }
                else
                {
                    // ↓
                    SendKeys.SendWait( "↓" );

                }
            }
            else if ( _IsMacro )
            {

                KeyEventOnceMacroZtoM( _MacroType._ZtoM[ 6 ] );
            }
            else if ( !_IsFunction )
            {
                KeyEventSingle( WinApi.VirtualKeys.VK_M );
                SetAutoCompleteBufferChar( "ㅡ", "ㅡ", "M", "m" );
            }

            StartStoryboardKeyboard( Btn_M );
        }

        public void KeyEventEsc ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_ESCAPE );

            StartStoryboardKeyboard( Btn_Esc );
        }

        public void KeyEventFunction ()
        {
            _IsFunction = !_IsFunction;
            ChangeKeyboardState();

            StartStoryboardKeyboard( Btn_Function );
        }

        public void KeyEventMacro ()
        {
            _IsMacro = !_IsMacro;
            ChangeKeyboardState();




            ChangeKeyboardBackground( Btn_Macro, _IsMacro );


            //StartStoryboardKeyboard( Btn_Macro );
        }

        public void KeyEventRecycle ()
        {


            if ( !_RecycleBuffer.Equals( String.Empty ) )
            {
                WriteBluetoothSignal( _RecycleBuffer );
            }

            StartStoryboardKeyboard( Btn_Recycle );

        }

        public void KeyEventToggleAutoCompleteText ()
        {
            //자동완성 On / Off
            _IsAutoCompleteText = !_IsAutoCompleteText;
            ChangeKeyboardBackground( Btn_AutoCompleteOnOff, _IsAutoCompleteText );
            //StartStoryboardKeyboard( Btn_AutoCompleteOnOff );
        }


        public void UpdateAutoCompleteText()
        {
            //자동완성 On / Off
            

            _IsAutoCompleteText = _KeyboardOption.IsCheckAutoComplete;
            ChangeKeyboardBackground(Btn_AutoCompleteOnOff, _IsAutoCompleteText);
            //StartStoryboardKeyboard( Btn_AutoCompleteOnOff );
        }

        public void KeyEventBackMain ()
        {
            //메인으로 복귀
            _MainWindow.KillProcess();

            StartStoryboardKeyboard( Btn_BackMain );
        }

        public void KeyEventInsert ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_INSERT );

            StartStoryboardKeyboard( Btn_Insert );
        }

        public void KeyEventDelete ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_DELETE );

            StartStoryboardKeyboard( Btn_Delete );
        }

        public void KeyEventTab ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_TAB );

            StartStoryboardKeyboard( Btn_Tab );
        }

        public void KeyEventHome ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_HOME );


            StartStoryboardKeyboard( Btn_Esc );
        }

        public void KeyEventEnd ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_END );

            StartStoryboardKeyboard( Btn_End );
        }

        public void KeyEventCapsLock ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_CAPITAL );

            _IsCapsLock = !_IsCapsLock;
            ChangeKeyboardState();

            ChangeKeyboardBackground( Btn_CapsLock, _IsCapsLock );

            //StartStoryboardKeyboard(Btn_CapsLock);
        }

        public void KeyEventBackSpace ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_BACK );

            AutoCompleteBackSpace();

            StartStoryboardKeyboard( Btn_Back );
        }

        private void AutoCompleteBackSpace ()
        {
            if ( !_IsHangul && _AutoCompleteBufferEnglish.Length != 0 )
            {
                _AutoCompleteBufferEnglish = _AutoCompleteBufferEnglish.Remove( _AutoCompleteBufferEnglish.Length - 1, 1 );
                SearchAutoCompleteEvent( _AutoCompleteBufferEnglish );

                _IsBufferFull = true;
            }
            else if ( _Automata.getIngWordLength() != 0 )
            {
                _Automata.removeIngWord();
                _Automata.BackState();
                string tmpStr = _Automata.getCombineAll( "" );
                SearchAutoCompleteEvent( tmpStr );
                _IsBufferFull = true;
            }
            else
            {
                _Automata.removeIngCompleteText();
                string tmpStr = _Automata.getCombineAll( "" );
                SearchAutoCompleteEvent( tmpStr );
                this.Dispatcher.BeginInvoke( new NoParamDelegate( _AutoCompleteText.Hide ) );
                _Automata.CurrentStateReset();
                _IsBufferFull = false;
                this.Dispatcher.BeginInvoke( new NoParamDelegate( HideAutoCompleteText ) );
            }
        }

        public void KeyEventPageUp ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_PRIOR );

            StartStoryboardKeyboard( Btn_PageUp );
        }

        public void KeyEventPageDown ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_NEXT );

            StartStoryboardKeyboard( Btn_PageDown );
        }

        public void KeyEventToggleShift ()
        {

            if ( _IsNumber )
            {
                ToggleCurrentNumberPage();
            }
            else
            {
                _IsShift = !_IsShift;
                KeyEventToggle( WinApi.VirtualKeys.VK_LSHIFT, _IsShift );
            }

            ChangeKeyboardState();

            ChangeKeyboardBackground( Btn_Shift, _IsShift );
            //StartStoryboardKeyboard(Btn_Shift);
        }
        public void ToggleCurrentNumberPage ()
        {
            if ( _CurrentNumberPage == 1 )
            {
                _CurrentNumberPage = 2;
            }
            else
            {
                _CurrentNumberPage = 1;
            }
        }
        public void CloseAutoCompleteDropDown ()
        {
            _AutoCompleteText.citiesACB.IsDropDownOpen = false;
        }
        public void HideAutoCompleteText ()
        {
            if ( !_AutoCompleteText.citiesACB.IsKeyboardFocusWithin )
            {
                _AutoCompleteText.citiesACB.IsDropDownOpen = false;
                _AutoCompleteText.Hide();
            }

        }
        public void KeyEventEnter ()
        {


            ClearAutoCompleteBufferChar();
            ClearAutoCompleteBufferString();
            ClearAutoCompleteBufferEnglish();
            _Automata.ClearCompleteText();
            _Automata.CurrentStateReset();

            this.Dispatcher.BeginInvoke( new NoParamDelegate( HideAutoCompleteText ) );
          
            KeyEventSingle( WinApi.VirtualKeys.VK_RETURN );

            StartStoryboardKeyboard( Btn_Enter );




        ;
        }

        public void KeyEventCtrl ()
        {
            //KeyEventSingle(WinApi.VirtualKeys.VK_LCONTROL);

            _IsCtrl = !_IsCtrl;
            KeyEventToggle( WinApi.VirtualKeys.VK_LCONTROL, _IsCtrl );

            ChangeKeyboardState();

            ChangeKeyboardBackground( Btn_Ctrl, _IsCtrl );

            //StartStoryboardKeyboard(Btn_Ctrl);
        }

        public void KeyEventWin ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_LWIN );

            StartStoryboardKeyboard( Btn_Win );
        }

        public void KeyEventAlt ()
        {
            //KeyEventSingle(WinApi.VirtualKeys.VK_MENU);

            _IsAlt = !_IsAlt;

            KeyEventToggle( WinApi.VirtualKeys.VK_MENU, _IsCtrl );

            ChangeKeyboardState();

            ChangeKeyboardBackground( Btn_Alt, _IsAlt );

            //StartStoryboardKeyboard(Btn_Alt);
        }

        public void KeyEventHanja ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_HANJA );

            StartStoryboardKeyboard( Btn_Hanja );
        }

        public void KeyEventSpace ()
        {

            ClearAutoCompleteBufferChar();
            ClearAutoCompleteBufferString();
            ClearAutoCompleteBufferEnglish();
            _Automata.ClearCompleteText();
            _Automata.CurrentStateReset();
            this.Dispatcher.BeginInvoke( new NoParamDelegate( _AutoCompleteText.Hide ) );

            KeyEventSingle( WinApi.VirtualKeys.VK_SPACE );
            StartStoryboardKeyboard( Btn_Space );
        }

        public void KeyEventToggleHanEng ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_HANGUL );

            _IsHangul = !_IsHangul;
            ChangeKeyboardState();

            StartStoryboardKeyboard( Btn_HanEng );
        }

        public void KeyEventToggleNumberCharacter ()
        {
            // 숫자 영어 변환 

            if ( _IsFunction )
            {
                _IsFunction = !_IsFunction;

                _IsNumber = false;
            }
            else if ( _IsMacro )
            {
                _IsMacro = !_IsMacro;

                _IsNumber = false;
            }
            else
            {
                _IsNumber = !_IsNumber;
            }


            ChangeKeyboardState();

            StartStoryboardKeyboard( Btn_Number );
        }

        public void KeyEventComma ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_OEM_COMMA );

            StartStoryboardKeyboard( Btn_Comma );
        }

        public void KeyEventPeriod ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_OEM_PERIOD );

            StartStoryboardKeyboard( Btn_Dot );
        }

        public void KeyEventUp ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_UP );

            StartStoryboardKeyboard( Btn_Up );
        }

        public void KeyEventDown ()
        {

            AutoCompleteText._IsFocusDropDown = false;

            if ( _Automata.getCombineSize() != 0 || _AutoCompleteBufferEnglish.Length != 0 )
            {
                Console.WriteLine( "combinesize {0}", _Automata.getCombineSize() );

                _AutoCompleteText.setFocusAutoComplete();
            }

            Thread.Sleep( 50 );

            KeyEventSingle( WinApi.VirtualKeys.VK_DOWN );

            StartStoryboardKeyboard( Btn_Down );
        }

        public void KeyEventLeft ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_LEFT );

            StartStoryboardKeyboard( Btn_Left );
        }

        public void KeyEventRight ()
        {
            KeyEventSingle( WinApi.VirtualKeys.VK_RIGHT );

            StartStoryboardKeyboard( Btn_Right );
        }


        /// <summary>
        /// 윈도우 크기 변경
        /// </summary>
        public void KeyEventChangeWindowSize ()
        {
            this.Dispatcher.BeginInvoke( new NoParamDelegate( ChangeWindowSize ) );

            StartStoryboardKeyboard( Btn_WindowSize );
        }

        /// <summary>
        /// 윈도우 숨김, 보임 토글
        /// </summary>
        public void KeyEventToggleHideShow ()
        {
            this.Dispatcher.BeginInvoke( new NoParamDelegate( ToggleWindowHideShow ) );
        }

        #endregion

        #region 블루투스에서 호출하는 함수



        /// <summary>
        /// 블루투스와 통신하는 함수
        /// </summary>
        /// <param name="data">전달된 string 신호</param>
        public void WriteBluetoothSignal ( string data )
        {

            // 리사이클 신호를 제외한 나머지 신호를 리사이클 버퍼에 담기
            if ( !data.Equals( "-" ) )
            {
                _RecycleBuffer = data;
            }

            OnceSignal( data );

            if ( _BluetoothKeyEvents != null && _CustomSignal != null )
            {
                int index = -1;
                index = _CustomSignal.IndexOf( data );

                if ( index != -1 )
                {
                    _BluetoothKeyEvents[ index ]();
                }
            }
        }


        private delegate void RequestSignalDelegate ( Image str );
        private void OnceSignal ( string str )
        {

            this.Dispatcher.Invoke( new RequestSignalDelegate( RequestSignalWindow ), this.Dispatcher.Invoke( new GetSignalImageDelegate( GetSignalImage ), str ) );
        }

        private void RequestSignalWindow ( Image myImage )
        {
            if ( !MainWindow._IsSignal )
            {
                _MainWindow._Signal = new Signal();
                MainWindow._IsSignal = true;
            }

            _MainWindow._Signal.Left = 0;
            _MainWindow._Signal.Top = 0;
            _MainWindow._Signal.Content = myImage;

            if ( MainWindow._IsSignal )
                _MainWindow._Signal.Show();

        }


        private delegate Image GetSignalImageDelegate ( string path );

        private Image GetSignalImage ( string path )
        {
            System.Windows.Controls.Image myImage = new System.Windows.Controls.Image();

            string tmpStr = path;
            tmpStr = tmpStr.Replace( ".", "dot" );
            tmpStr = tmpStr.Replace( "-", "dash" );

            // 소스 생성

            BitmapImage myBitmapImage = new BitmapImage();

            // BitmapImage.UriSource는 반드시 BeginInit/EndInit 블럭 내에 있어야 합니다.

            myBitmapImage.BeginInit();

            myBitmapImage.UriSource = new Uri( @"../../Image/dashdot/_" + tmpStr + ".png", UriKind.Relative );


            myBitmapImage.EndInit();

            // 이미지 소스 설정

            myImage.Source = myBitmapImage;
            return myImage;
        }

        private void KeyEventShowOption ()
        {
            this.Dispatcher.BeginInvoke( new NoParamDelegate( ShowOptionDialog ) );
        }

        private void ShowOptionDialog ()
        {
            if (!CustomKeyboard._IsShow)
            {             
                new CustomKeyboard(_MainWindow._ScreenKeyboard, _MainWindow._ScreenMouse, true).Show();
            }
        }


        public void SetAutoCompleteBufferChar ( string han_default, string han_shift, string eng_upper, string eng_lower )
        {

            if ( _CurrentKeyboardState == _KeyboardStateType.KoreanDefault )
            {
                _AutoCompleteBufferChar = han_default;
            }
            else if ( _CurrentKeyboardState == _KeyboardStateType.KoreanShift )
            {
                _AutoCompleteBufferChar = han_shift;
            }
            else if ( _CurrentKeyboardState == _KeyboardStateType.EnglishUpper )
            {
                _AutoCompleteBufferChar = eng_upper;
            }
            else
            {
                _AutoCompleteBufferChar = eng_lower;
            }

            _IsBufferFull = true;
        }

        public void ClearAutoCompleteBufferChar ()
        {
            _AutoCompleteBufferChar = "";
        }

        public void ClearAutoCompleteBufferString ()
        {
            _AutoCompleteBufferString = "";
        }

        public void ClearAutoCompleteBufferEnglish ()
        {
            _AutoCompleteBufferEnglish = "";
        }

        public void WriteBluetoothAutoCompleteText ()
        {

            this.Dispatcher.BeginInvoke( new NoParamDelegate( OnceAutoCompleteText ) );


        }

        public bool checkActiveACT ()
        {
            IntPtr hwnd = WinApi.GetForegroundWindow();
            int processID = 0;
            int threadID = WinApi.GetWindowThreadProcessId( hwnd, out processID );
            bool result = false;
            Console.WriteLine( "parent name = " + Process.GetProcessById( processID ).ProcessName );
            switch ( Process.GetProcessById( processID ).ProcessName )
            {
                case "Hwp":


                case "WINWORD":


                case "POWERPNT":

                case "EXCEL":

                case "notepad":

                case "JungUmGW":

                case "devenv":

                    result = true;
                    break;

                default:

                    break;
            }
            return result;
        }


        public bool CheckBrowser ()
        {
            IntPtr hwnd = WinApi.GetForegroundWindow();
            int processID = 0;
            int threadID = WinApi.GetWindowThreadProcessId( hwnd, out processID );
            bool result = false;
            Console.WriteLine( "parent name = " + Process.GetProcessById( processID ).ProcessName );
            switch ( Process.GetProcessById( processID ).ProcessName )
            {
                case "Firefox":


                case "iexplore":


                case "chrome":


                    result = true;
                    break;

                default:

                    break;
            }
            return result;
        }

        private delegate void SearchAutoComplete ( string str );
        private void SearchAutoCompleteEvent ( string str )
        {
            this.Dispatcher.BeginInvoke( new SearchAutoComplete( _AutoCompleteText.searchAutoComplete ), str );
        }
        private void OnceAutoCompleteText ()
        {
            if ( checkActiveACT() && _IsBufferFull && _IsAutoCompleteText )
            {


                _AutoCompleteText.setPosition();

                //Thread.Sleep( 1 );
                _AutoCompleteText.Show();

                _AutoCompleteBufferString = _AutoCompleteBufferChar;
                _AutoCompleteBufferEnglish += _AutoCompleteBufferChar;
                ClearAutoCompleteBufferChar();
                AutoCompleteText._IsFocusDropDown = true;

                string temp = "";
                if ( _CurrentKeyboardState == _KeyboardStateType.KoreanDefault || _CurrentKeyboardState == _KeyboardStateType.KoreanShift )
                {
                    temp = _Automata.getCombineAll( _AutoCompleteBufferString );
                    AutoCompleteText.BufferSize = _Automata.getCombineSize();
                }
                else
                {
                    temp = _AutoCompleteBufferEnglish;
                    AutoCompleteText.BufferSize = _AutoCompleteBufferEnglish.Length;
                }


                SearchAutoCompleteEvent( temp );



                //ClearAutoCompleteBufferString();


                _IsBufferFull = false;
            }
        }

        public void CloseAutoCompleteText ()
        {
            if ( this._AutoCompleteText != null )
            {
                this._AutoCompleteText.Close();
            }

        }
        #endregion

        #region 키보드 쉬프트, 한영, 숫자 컨텍스트


        /// <summary>
        /// 쉬프트 누를때 이미지 변경하기
        /// </summary>
        /// <param name="path">이미지 경로</param>
        private void ChangeShiftImage ( string path )
        {
            try
            {
                Image image = (Image)Btn_Shift.Template.FindName( "image", Btn_Shift );
                ImageBrush imgBrush = new ImageBrush();
                imgBrush.ImageSource = new BitmapImage( new Uri( @"" + path, UriKind.Relative ) );
                imgBrush.Stretch = Stretch.Fill;
                image.Source = imgBrush.ImageSource;
            }
            catch ( Exception ex01 )
            {
                Debug.WriteLine( "ChangeShiftImage Error - " + ex01.Message );
            }
        }


        #endregion


    }
}
